package com.yoofn.nbwk.base

import android.os.Handler
import android.os.Looper
import android.text.TextUtils
import android.util.Log
import com.yanzhenjie.nohttp.NoHttp
import com.yanzhenjie.nohttp.rest.OnResponseListener
import com.yanzhenjie.nohttp.rest.Response
import com.yoofn.kotlin.base.GlobalConfig
import com.yoofn.kotlin.base.NetData

/**
 * Created by kalshen on 2017/7/20.
 * @描述 项目网络请求框架封装
 */
interface HttpFramework {


    /**
     * 用于增加网络请求
     * @param netData 网络请求参数
     */
    fun <RequestType : Any> addRequest(netData: NetData<RequestType>?) {
        initNetParams(netData)
    }

    /**
     * 配置网络请求request 和 response
     * @param netData 网络请求实体对象
     */
    private fun <RequestType : Any> initNetParams(netData: NetData<RequestType>?) {
        //如果netData 为null 直接退出请求
        if (netData == null) {
            return
        }
        //避免反复请求，将触发请求的view设为 enable = false
        netData.actionView?.isEnabled = false

        //打印网络日志
        val tag = GlobalConfig.HTTP_CATCH_SIMPLE_LOG_TAG
        if (GlobalConfig.IS_ENABLE_REQUEST_LOG) {
            val paramKeyValues = netData.request.paramKeyValues
            val info = StringBuilder()
            paramKeyValues.entrySet().forEach { info.append("\n${it.key}:${it.value}") }
            Log.d(tag, "--------------Request start--------------")
            Log.i(tag, "Request address:${netData.request.url()}")
            Log.i(tag, "Request method:${netData.request.requestMethod}")
            Log.i(tag, "Content-Type:${netData.request.contentType}")
            Log.i(tag, "Request-Type:${netData.request::class.java.simpleName}")
            Log.i(tag, "params：${if (TextUtils.isEmpty(info.toString())) "empty" else info.toString()}")
        }

        //将请求加入请求队列
        NoHttp.getRequestQueueInstance().add(netData.what, netData.request, object : OnResponseListener<RequestType> {

            //请求开始时
            override fun onStart(p0: Int) {
                if (netData.dialog == null) {
                    //fixme 暂时先不提供默认的progress
                    /* val dialog = ProgressDialog(activity)
                     dialog.setMessage("正在加载数据...")
                     netData.dialog = dialog*/
                }
                netData.dialog?.show()
                onRequestStart(p0)
            }

            //请求结束后
            override fun onFinish(p0: Int) {
                netData.dialog?.dismiss()
                netData.actionView?.isEnabled = true
                onRequestFinished(p0)
            }

            //请求成功时
            override fun onSucceed(p0: Int, p1: Response<RequestType>?) {
                //打印http response log
                if (GlobalConfig.IS_ENABLE_RESPONSE_LOG) {
                    Log.e(tag, "--------------Response success--------------")

                }
                p1?.let {
                    if (it.isSucceed) {
                        //将网络回调 执行到主线程去
                        Handler(Looper.getMainLooper()).post { doBusiness(p0, it) }
                    }
                }


            }

            //请求失败时
            override fun onFailed(p0: Int, p1: Response<RequestType>?) {
                //打印http log
                if (GlobalConfig.IS_ENABLE_RESPONSE_LOG) {
                    Log.e(tag, "--------------Response error--------------")
                    Log.e(tag, "error: con't access to remote server")
                }
                //TODO 这里可以优化统一请求失败后的结果
                onRequestFailed(p0, p1)
            }
        })
    }


    /**
     * 请求开始
     */
    fun onRequestStart(what: Int) {

    }

    /**
     * 请求结束
     */
    fun onRequestFinished(what: Int) {

    }

    /**
     * 请求失败
     */
    fun <RequestType> onRequestFailed(what: Int, response: Response<RequestType>?) {

    }

    /**
     * 用于处理业务逻辑(网络访问已经成功)
     * @param what 区别网络请求
     * @param response 请求返回经过类型处理的的response.get()对象
     *                     如果请求是StringRequest 则 返回的responseBody是String
     *                     如果请求是JsonObjectRequest 则 返回的responseBody是JsonObject
     *                     这个返回类型是根据 {@link NetData} 类中的的 request 泛型决定
     */
    fun <RequestType> doBusiness(what: Int, response: Response<RequestType>)
}